package com.example.photoview;

import com.example.showImage.ImageController;
import com.example.showImage.ImageWindow;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.*;
import javafx.stage.Stage;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;
import java.util.Stack;

public class HomeController  implements Initializable {
    private HomeController mainUI;
    private ArrayList<ImageList> pictures;
    private ArrayList<File> files;
    public static String theFilePath;
    @FXML
    public Button pasteButton;
    @FXML
    public TextField searchTextField;
    @FXML
    public Button closeSearchButton;
    @FXML
    public Button gotoButton;
    @FXML
    public AnchorPane anchorPane;
    @FXML
    public Button selectAllButton;
    @FXML
    private Button refreshButton;
    @FXML
    private ToolBar infoBar;
    @FXML
    private Label folderInfoLabel;
    @FXML
    public Label selectedNumLabel;

    public void setSortComboBox(ComboBox<String> sortComboBox) {
        this.sortComboBox = sortComboBox;
    }

    /**
     * startNum lengthNum
     */
    private int startNum=1;
    private String lengthNum="4";

    public int getStartNum() {
        return startNum;
    }

    public void setStartNum(int startNum) {
        this.startNum = startNum;
    }

    public String getLengthNum() {
        return lengthNum;
    }

    public void setLengthNum(String lengthNum) {
        this.lengthNum = lengthNum;
    }

    @FXML
    private ComboBox<String> sortComboBox;
    private boolean comboBoxClicked=false;
    @FXML
    private TextField pathTextField;
    //面板
    @FXML
    private StackPane rootPane;
    @FXML
    private FlowPane imageListPane =new FlowPane();
    @FXML
    private  Button backButton;
    /*@FXML
    private  ScrollPane scrollPane;*/

////    public ScrollPane getScrollPane() {
////        return scrollPane;
////    }
////
//    public void initScrollPane() {
//
//
//        StackPane stackPane=new StackPane();
//        scrollPane.setContent(stackPane);
//        TreeViewController treeViewController =new TreeViewController();
//        stackPane.getChildren().add(treeViewController.getTreeView());
//    }

    @FXML
    private ScrollPane scrollPane;
    @FXML
    private AnchorPane folderPane;
    @FXML
    private Button forwardButton;

    public String getCurrentPath() {
        return currentPath;
    }

//    public void setCurrentPath(String currentPath) {
//        this.currentPath = currentPath;
//    }

    private ImageController imageController;
    //存储信息的变量
    private String currentPath="";
    private Stack<String> pathStack1 = new Stack<>();
    private Stack<String> pathStack2 = new Stack<>();
    /**当前图片列表*/
    private ArrayList<ImageModel> curImgList=new ArrayList<>();

    public HomeController(){
        //将本类的实例添加到全局映射中
        ControllerUtil.controllers.put(this.getClass().getSimpleName(), this);
    }
    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        imageListPane.setPadding(new Insets(10));
        imageListPane.setVgap(10);
        imageListPane.setHgap(10);
        imageListPane.setCache(true);//缓存
      //  System.out.println(imageListPane.getLayoutX()+" "+imageListPane.getLayoutY());
        SplitPane.setResizableWithParent(folderPane, false);//不可改变大小


        infoBar.setBackground(Background.EMPTY); //信息栏设置透明背景
        closeSearchButton.setVisible(false);

        initPasteButton();//初始化粘贴按钮
        initSortComboBox();//初始化排序

        initIntroPage();       //设置欢迎页必须在scrollPane之后设置，否则会被imageListPane空白页覆盖
        initSearchTextField();//初始化搜索框
        initPathTextField();//初始化路径文本框

    }
    // 缩略图面板层级（从底到顶）:
    // AnchorPane > ScrollPane > FlowPane(imageListPane)
    public void placeImages(ArrayList<ImageModel> imageModelList, String folderPath) {
        //检查列表是否空，因为有可能处于初始页面
        if (imageModelList == null)
            return;

        // 每次生成前重置
        imageListPane.getChildren().clear();
        scrollPane.setContent(imageListPane);
        SelectionModel.clear();
        unSelectAll();
        sortComboBox.setVisible(true); //默认排序盒子不出现，除非触发了构建缩略图操作

        //设置初始加载数目,更改时需要更改滚动内的初始index值
        int firstLoad = Math.min(imageModelList.size(), 10000);    // 修改了firstLoad 取值为列表与10000之间的最小值

        //更新当前地址，并检测入栈
        pathTextField.setText(folderPath);
        currentPath = folderPath;

        //文件夹信息栏设置
        if (imageModelList.isEmpty()) {
            folderInfoLabel.setText("此文件夹下无可识别图片");
            return;
        } else {
            int total = ImageList.getListImgNum(imageModelList);
            String size = ImageList.getListImgSize(imageModelList);
            folderInfoLabel.setText(String.format("%d 张图片，共 %s ", total, size));
            selectedNumLabel.setText("| 已选中 0 张");
        }
        //TODO 新建新线程执行加载任务 可大幅缓解在图片较多时的卡顿情况
        //初始加载 firstload 张缩略图
        int i;
        for (i = 0; i < firstLoad; i++) {
            ImageBox imageBox = new ImageBox(imageModelList.get(i)); //装图片和文件名的盒子，一上一下放置图片和文件名
            imageListPane.getChildren().add(imageBox);
        }

        //加载后续的缩略图

        imageListPane.setOnScroll(new EventHandler<ScrollEvent>() {
            //初始加载后的位置
            int index = firstLoad - 1;

            @Override
            public void handle(ScrollEvent event) {
                int times = 30; // 每次滚动加载30张
                while (times > 0) {
                    index++;
                    if (event.getDeltaY() <= 0 && index < imageModelList.size()) {
//                    WAR/WAW ERROR
//                    index = loadPic(imageModelList, imageListPane, index);
                        ImageBox imageBox = new ImageBox(imageModelList.get(index)); //装图片和文件名的盒子，一上一下放置图片和文件名
                        imageListPane.getChildren().add(imageBox);
                    } else {
                        break;
                    }
                    times--;
                }

            }
        });
    }

    /**
     * 排序当前图片列表并刷新图片列表
     */
    public void refreshImagesList(String sort) {
        SelectionModel.clear();
        SelectedModel.getSourcePathList().clear();
        curImgList = ImageList.refreshListStr(currentPath,sort);
        System.out.println("curImList is:"+curImgList);
        placeImages(curImgList, currentPath);
    }

    public void initEnterFolder(String path) {
        currentPath = path;
        //入栈以便于后续前进后退
        if (pathStack1.isEmpty() || !pathStack1.peek().equals(path)) {
            pathStack1.push(path);
            pathStack2.clear();
        }
        placeImages(ImageList.refreshList(currentPath), currentPath);
    }

    // 以下是一些初始化操作----------------
    @FXML
    private void initIntroPage() {
        StackPane stackPane = new StackPane();
        scrollPane.setContent(stackPane);//叠多一个StackPane
    }

    public void showNotFoundPage() {

      ImageView img = new ImageView();//TODO 修改图片位置
        Image image=new Image(getClass().getResourceAsStream("/image/no_result.png"));
     img.setImage(image);
       // ImageView img=new ImageView(new Image(getClass().getResource("文件路径").toExternalForm()));
        //TO DO找了
        System.out.println("showNotFoundPage");
        img.setFitHeight(500);
        img.setPreserveRatio(true);
        HBox hBox = new HBox(img);
        hBox.setAlignment(Pos.CENTER);
        StackPane stackPane = new StackPane(hBox);
        scrollPane.setContent(stackPane);
    }

    /**
     * 初始化排序下拉盒子
     */
    private void initSortComboBox() {
        sortComboBox.getItems().addAll(SortParam.SBNR, SortParam.SBND, SortParam.SBSR, SortParam.SBSD, SortParam.SBDR, SortParam.SBDD);
        sortComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                refreshImagesList(newValue);
                if (!comboBoxClicked)
                    setComboBoxClicked(true);
            }
        });
    }

    private void initSearchTextField() {
        searchTextField.setOnKeyPressed(event -> {
            if (event.getCode() == KeyCode.ENTER)
                searchImage();
        });
    }

    private void initPathTextField() {
        pathTextField.setOnKeyPressed(event -> {
            System.out.println("123");
            if (event.getCode() == KeyCode.ENTER){
                System.out.println("234");
                gotoPath();
                System.out.println("345");
            }


        });
    }

    private void initPasteButton() {
        if (SelectedModel.getSourcePath() == null || SelectedModel.getCopyOrMove() == -1) {
            pasteButton.setDisable(true);
        }
    }

    private void  initShowUpButton(){
        this.imageController=new ImageController();
    }

    //各按钮事件操作------------------

    /**
     * 前进、后退和返回父目录
     */
    @FXML
    private void moveBack() {
        if (!pathStack1.isEmpty()) {
          //  backButton.setDisable(false);
            if (pathStack1.peek().equals(currentPath)) {
                pathStack1.pop();
            }
            try {
                String path = pathStack1.pop();
                pathStack2.push(currentPath);
                placeImages(ImageList.refreshList(path), path);
            }catch(Exception e){
                System.out.println("NULL stack,nothing error");
            }

        } else {
          //  backButton.setDisable(true);
            Alert alert=new Alert(Alert.AlertType.WARNING);
            alert.setTitle("Warning");
            alert.setHeaderText(null);
            alert.setContentText("后退到底啦！");
            alert.showAndWait();
        }
    }

    @FXML
    private void moveForward() {
        if (!pathStack2.isEmpty()) {
           // forwardButton.setDisable(false);
            String path = pathStack2.pop();
            pathStack1.push(currentPath);
            placeImages(ImageList.refreshList(path), path);
        } else {
          //  forwardButton.setDisable(true);
            Alert alert=new Alert(Alert.AlertType.WARNING);
            alert.setTitle("Warning");
            alert.setHeaderText(null);
            alert.setContentText("前进到尽头啦！");
            alert.showAndWait();
        }
    }

    @FXML
    private void toParentDir() {
        String parent;
        if (currentPath.lastIndexOf("\\") == 2) {
            if (currentPath.length() == 3) {
                Alert alert=new Alert(Alert.AlertType.WARNING);
                alert.setTitle("Warning");
                alert.setHeaderText(null);
                alert.setContentText("已到达根目录");
                return;
            } else {
                parent = currentPath.substring(0, currentPath.lastIndexOf("\\") + 1);
            }
        } else {
            parent = currentPath.substring(0, currentPath.lastIndexOf("\\"));
        }
        placeImages(ImageList.refreshList(parent), parent);
        pathStack1.push(parent);
    }

    /**
     * 地址栏导航操作
     */
    @FXML
    private void gotoPath() {
        String path = pathTextField.getText();
        //用于处理以反斜杠 "\" 结尾的情况，需去掉反斜杠
        //(导航至磁盘根目录 即路径地址长度等于3的情况 除外)
        if (path.endsWith("\\") && path.length() != 3)
            path = path.substring(0, path.length() - 1);

        File directory = new File(path);
        if (!directory.exists()) {
            Alert alert=new Alert(Alert.AlertType.WARNING);
            alert.setTitle("Warning");
            alert.setHeaderText(null);
            alert.setContentText("路径不正确！");
        } else {
            ArrayList<ImageModel> list = ImageList.refreshList(path);
            // placeImages方法中已处理列表为空时的情况
            if (list != null)
                placeImages(list, path);
        }
    }

    /**
     * 刷新按钮操作
     */
    @FXML
    private void refresh() {
        unSelectAll();
        closeSearch();
        refreshImagesList(sortComboBox.getValue());
        //   snackbar.enqueue(new JFXSnackbar.SnackbarEvent("已刷新"));//下方透明的提示栏
        Alert alert=new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("操作消息");
        alert.setHeaderText(null);
        alert.setContentText("已刷新");
    }

    /**
     * 粘贴按钮操作
     */
    @FXML
    private void paste() throws IOException {
          SelectedModel.paste(currentPath);
        if (SelectedModel.getHavePastedNum() == SelectedModel.getWaitingPasteNum()) {
            Alert alert=new Alert(Alert.AlertType.INFORMATION);
            alert.setTitle("操作消息");
            alert.setHeaderText(null);
            alert.setContentText("粘贴成功");
            refreshImagesList(sortComboBox.getValue());
        }
        if (SelectedModel.getSourcePath() == null || SelectedModel.getCopyOrMove() == -1) {
            pasteButton.setDisable(true);
        }
    }

    @FXML
    private void searchImage() {
        String key = searchTextField.getText();
        curImgList = ImageList.refreshList(currentPath);
        System.out.println("curImList is:"+curImgList);
        placeImages(curImgList, currentPath);
        if (key.equals("")) {
            Alert alert=new Alert(Alert.AlertType.WARNING);
            alert.setTitle("提示");
            alert.setHeaderText(null);
            alert.setContentText("搜索内容为空");
            alert.showAndWait();
            return; // 搜索内容为空时即返回
        }
        System.out.println(curImgList);
        ArrayList<ImageModel> result =
                SearchImgModel.fuzzySearch(key, curImgList);//查找功能

        placeImages(result, currentPath);
        if (result.size() == 0) {
            folderInfoLabel.setText("未找到图片");
            showNotFoundPage();
        } else {
            folderInfoLabel.setText("共找到 " + result.size() + " 个结果");
        }
        closeSearchButton.setVisible(true);
    }

    /**
     * 关闭搜索
     */
    @FXML
    private void closeSearch() {
        closeSearchButton.setVisible(false);
        searchTextField.setText("");
        refreshImagesList(sortComboBox.getValue());
    }

    /**
     * 全选按钮
     */
    @FXML
    private void selectAll() {
        //如果没有可选的内容
        if (imageListPane.getChildren().isEmpty()) {
            Alert alert=new Alert(Alert.AlertType.WARNING);
            alert.setTitle("Warning");
            alert.setHeaderText(null);
            alert.setContentText("无内容可选");
            alert.showAndWait();
            return;
        }
        //避免重复选择，先清空已选
        SelectionModel.clear();
        for (Node node : imageListPane.getChildren()) {
            ImageBox imageBox = (ImageBox) node;
            imageBox.getCheckBox().setSelected(true);
        }
    }

    /**
     * 清空选择
     */
    @FXML
    private void unSelectAll() {
        SelectionModel.clear();
    }

    public void SelectAllAction(){
        //如果没有可选的内容
        if (imageListPane.getChildren().isEmpty()) {
            Alert alert=new Alert(Alert.AlertType.WARNING);
            alert.setTitle("Warning");
            alert.setHeaderText(null);
            alert.setContentText("无内容可选");
            alert.showAndWait();
            return;
        }
        //避免重复选择，先清空已选
        SelectionModel.clear();
        for (Node node : imageListPane.getChildren()) {
            ImageBox imageBox = (ImageBox) node;
            imageBox.getCheckBox().setSelected(true);
        }
    }
    @FXML
    /**
     * 这个就是新加入的imageController的PPT放映函数
     */
    private void startShowUp(){

        System.out.println("HomeController -- startShowUp function started");
        ImageWindow dw = new ImageWindow();
        ImageModel imgMod=null;
        curImgList = ImageList.refreshList(currentPath);
        if(curImgList.size()==0){
            //curImgList = ImageList.refreshList(currentPath);
            Alert alert=new Alert(Alert.AlertType.WARNING);
            alert.setTitle("提示");
            alert.setHeaderText(null);
            alert.setContentText("该文件下无图片，请更换文件夹");
            alert.showAndWait();
            return;
        }else {
             imgMod = curImgList.get(0);
        }
        System.out.println(curImgList);
        dw.setImage(imgMod);
        //System.out.println("hjgkj");

        dw.start(new Stage());//产生看图片界面


        //imageController.showUp();
    }




    public ComboBox<String> getSortComboBox() {
        return sortComboBox;
    }

    public void setComboBoxClicked(boolean comboBoxClicked) {
        this.comboBoxClicked = comboBoxClicked;
    }

    /**
     * 是否选择复选框
     * @return
     */
    public boolean isComboBoxClicked() {
        return comboBoxClicked;
    }

    public  Button getPasteButton() {
        return pasteButton;
    }

    public FlowPane getImageListPane() {
        return imageListPane;
    }

    public AnchorPane getFolderPane() {
        return folderPane;
    }

    public AnchorPane getAnchorPane() {
        return anchorPane;
    }

    public ScrollPane getScrollPane() {
        return scrollPane;
    }
}
